#include "jcewriter.h"

int JceWriter::JCE_MAX_STRING_LENGTH = 104857600;

JceWriter::JceWriter(QSharedPointer<QByteArray> output):DataWriter(output)
{

}

JceWriter &JceWriter::setServerEncoding(bool isGBK)
{
    sServerEncodingGBK = isGBK;
    return *this;
}

JceWriter &JceWriter::writeHead(JceWriter::JceDataType type, int tag)
{
    if(tag < 15)DataWriter::writeByte(tag<<4 | (qint8)type);
    else if(tag < 0x100)DataWriter::writeByte((qint8)type | 0xF0).writeByte(tag);
    else abort();//wtf you input the shit params???
    return *this;
}

JceWriter &JceWriter::writeInt(int tag, int data)
{
    if(data >= SHRT_MIN && data <= SHRT_MAX)
        JceWriter::writeShort(tag,data);
    else {
        JceWriter::writeHead(JceDataType::INT,tag);
        DataWriter::writeInt(data);
    }
    return *this;
}

JceWriter &JceWriter::writeByte(int tag, qint8 data)
{
    if(data == 0)
        writeHead(JceDataType::ZERO_TYPE,tag);
    else {
        writeHead(JceDataType::BYTE,tag);
        DataWriter::writeByte(data);
    }
    return *this;
}

JceWriter &JceWriter::writeShort(int tag, short data)
{
    if(data >= CHAR_MIN && data <= CHAR_MAX)
        JceWriter::writeByte(tag,data);
    else {
        writeHead(JceDataType::SHORT,tag);
        DataWriter::writeShort(data);
    }
    return *this;
}

JceWriter &JceWriter::writeLong(int tag, qint64 data)
{
    if(data >= INT_MIN && data <= INT_MAX)
        JceWriter::writeInt(tag,data);
    else {
        writeHead(JceDataType::LONG,tag);
        DataWriter::writeLong(data);
    }
    return *this;
}

JceWriter &JceWriter::writeNull(int tag)
{
    //writeHead(JceDataType::ZERO_TYPE,tag);
    return *this;
}

JceWriter &JceWriter::writeBytes(int tag, const QByteArray &data)
{
    if(data.size() == 0)return writeNull(tag);
    JceWriter::writeHead(JceDataType::SIMPLE_LIST,tag);
    JceWriter::writeHead(JceDataType::BYTE,0);
    JceWriter::writeInt(0,data.size());
    DataWriter::writeRaw(data);
    return *this;
}

JceWriter &JceWriter::writeString(int tag, const QString &data)
{
    //if(data.size() == 0)return writeNull(tag);
    if(data.length() > JCE_MAX_STRING_LENGTH)abort();//the length is too long
    QByteArray tmp = sServerEncodingGBK?data.toLatin1():data.toUtf8();
    if(tmp.size() > 255){
        writeHead(JceDataType::STRING4,tag);
        DataWriter::writeInt(tmp.size());
        DataWriter::writeRaw(tmp);
    }else{
        writeHead(JceDataType::STRING1,tag);
        DataWriter::writeByte(tmp.size());
        DataWriter::writeRaw(tmp);
    }
    return *this;
}

JceWriter &JceWriter::writeFloat(int tag, float data)
{
    writeHead(JceDataType::FLOAT,tag);
    DataWriter::writeFloat(data);
    return *this;
}

JceWriter &JceWriter::writeDouble(int tag, double data)
{
    writeHead(JceDataType::DOUBLE,tag);
    DataWriter::writeDouble(data);
    return *this;
}

JceWriter &JceWriter::writeStruct(int tag, JceWriter &data)
{
    writeHead(JceDataType::STRUCT_BEGIN,tag);
    DataWriter::writeRaw(*(data.serialize().getData()));
    writeHead(JceDataType::STRUCT_END,tag);
    return *this;
}

QSharedPointer<QByteArray> JceWriter::getData()
{
    return DataWriter::getData();
}
